今天要來介紹一個比較抽象的觀念,但在 K8s 中很常拿來使用,其實筆者從一開始的文章就開始埋下 Namespace 的坑,很多套件都會用到 Namespace 的觀念,像是 Ingress Controller 有一個 ingress-nginx
的 Namespace、Service 的 ExternalName 也是為了 Namespace 而有型態,所以今天的文章就來好好談談 Namespace 吧!
Namespace 是抽象的 cluster,讓我們能根據專案不同,將原本擁有實體資源的單一 cluster,劃分成幾個不同的 virtual cluster,我們都知道 cluster 是用來管理所有在此 cluster 下的機器,每台機器內運行的內容彼此是不能互相干擾的。
假如今天有一個情景是:有一個產品要分成開發版本跟上線版本,當然最簡單的分法就是直接把 Pod 的 Label 用不同的方式貼上去,再分別建立彼此的 Service 跟 Ingress,表現上看起來合理但實際上會發現很難控管,因為全部都混雜在一起。
或許讀者可能會這麼想:沒有什麼事情是不能用錢解決的,如果有的話那就多加點錢,所以就直接多開幾個 cluster 裡面再包含其他的機器,這樣就可以達到環境切割的效果,的確是可以但這樣成本真的就太高了,所以 Namespace 就是為了這種情境而建立的。
有了 Namespace 後就可以把 cluster 內再進行環境切割,每個 Namespace 彼此是獨立運行且不能互相干擾的,如果用 cluster 的角度去想就是一個 Namespace 代表一個 cluster,只是這個 cluster 管的不是機器而是一個執行環境。
預設所有建立的 Pod 都會擺放在 default 這個 Namespace。
由於 Namespace 是要在 cluster 內切割執行環境,所以每個 Namespace 是不能重複命名的,不然就失去切割的效果了。
上面段落提到可以把 Namespace 想像成一個 cluster,所以可想而知當 cluster 消失了內部的物件也會跟著消失。
由於 Namespace 切割了執行環境,因此不同 Namespace 內的物件其實是無法互相存取的,換句話說我不能用 NamespaceA 的 Service 去存取 NamespaceB 的 Pod,即便我今天 Pod 的 Label 都設定一樣也是無法存取,除非用了 ExternalName 型態的 Service。
apiVersion: v1
kind: Namespace
metadata:
name: helloworld
Namespace 的寫法非常單純,只要建立一個 kind
為 Namespace
並把名稱命名為自己想取的名稱即可,所有的 Namespace 寫法都一樣。
這邊一樣用 apply
的參數建立 Namespace。
建立完後一樣可以用 get
的參數查看建立好的 Namespace。
建立完 Namespace 後接下來把之前所有寫好的檔案通通運行在剛創立好的 Namespace 中吧!由於寫法都一樣所以這邊筆者以 Deployment 作為範例。
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: helloworld
name: helloworld
spec:
# 下略
可以看到就在 metadata
這邊加上要運行的 Namespace 名稱即可,之後再用 apply
的方式在新的 Namespace 中建立新的物件,這邊讀者可能會有疑惑為什麼不能用 replace
呢?原因很簡單因為新的 Namespace 本身並沒有這些物件,每個 Namespace 都是獨立的所以才會用 apply
而不是 replace
。
假如像 ConfigMap 跟 Secrets 這種沒有先寫成一份檔案的要怎麼新增呢?這邊筆者要介紹一個新的參數 -n
,-n
代表 Namespace 所以只要在 -n
後面接上 Namespace 名稱即可。
之後要查看一樣可以用 get
這個參數,不過現在都轉移到新的 Namespace 而不是繼續使用預設的 default,所以之後的指令都必須要加上 -n
這個參數進去。
今天文章介紹完 Namespace,未來如果要切割 cluster 的內部環境就可以利用 Namespace 的方式,就不用花大錢建立更多的 cluster 了,但這邊筆者一個小提醒,雖然用 Namespace 切割好環境但每個 Namespace 使用的資源都是同一台機器,所以每個 Pod 的 Resource Qutoas 必須要定義好,不然就會很容易資源不夠用。
如果對於文章有任何問題都歡迎留言給我,那我們就下一篇文章見嘍~